package com.yugao.fintech.draper.message.queue.support.group;

import cn.hutool.core.util.TypeUtil;
import com.yugao.fintech.draper.message.queue.client.HazelcastMQTemplate;
import com.yugao.fintech.draper.message.queue.interceptor.HazelcastMessageInterceptor;
import com.yugao.fintech.draper.message.queue.message.AbstractGroupMessage;
import com.yugao.fintech.draper.message.queue.message.AbstractMessage;
import com.yugao.fintech.draper.message.queue.support.HazelcastMessageListener;
import lombok.Getter;
import lombok.Setter;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;

import java.util.List;

@Slf4j
@Getter
@Setter
public abstract class AbstractHazelcastGroupMessageListener<T extends AbstractGroupMessage> implements HazelcastMessageListener<T> {
    /**
     * 消息类型
     */
    private final Class<T> messageType;

    /**
     * 主题topic
     */
    private final String group;

    private HazelcastMQTemplate mqTemplate;

    @SneakyThrows
    protected AbstractHazelcastGroupMessageListener() {
        this.messageType = (Class<T>) TypeUtil.getTypeArgument(getClass(), 0);
        this.group = messageType.newInstance().getGroup();
    }

    @Override
    public void process(T message) {
        // 消费消息
        try {
            log.info("message:{}", message);
            // 消费前处理
            consumeMessageBefore(message);
            // 消费消息
            this.onMessage(message);
        } finally {
            // 消费后处理
            consumeMessageAfter(message);
        }
    }

    protected void consumeMessageAfter(AbstractMessage message) {
        List<HazelcastMessageInterceptor> interceptors = mqTemplate.getInterceptors();
        interceptors.forEach(interceptor -> interceptor.consumeMessageBefore(message));
    }

    protected void consumeMessageBefore(AbstractMessage message) {
        List<HazelcastMessageInterceptor> interceptors = mqTemplate.getInterceptors();
        for (int i = interceptors.size() - 1; i >= 0; i--) {
            interceptors.get(i).consumeMessageAfter(message);
        }
    }
}
